home *** CD-ROM | disk | FTP | other *** search
/ 17 Bit Software 6: Level 6 / 17 Bit - Level 6 (1998)(Epic Marketing)[!].iso / quartz / q0430.dms / q0430.adf / Patch / util.c < prev    next >
C/C++ Source or Header  |  1992-09-02  |  13KB  |  582 lines

  1. #include "EXTERN.h"
  2. #include "common.h"
  3. #include "INTERN.h"
  4. #include "util.h"
  5.  
  6. /* Rename a file, copying it if necessary. */
  7.  
  8.  
  9. #ifdef AMIGA
  10.  
  11. #include <libraries/dos.h>
  12. #include <libraries/dosextens.h>
  13.  
  14.  
  15. /* backup & copy the file */
  16.   static void copy_file();
  17.  
  18. int
  19. move_file(from,to)
  20.  char *from, *to;
  21. {
  22.   register long success;
  23.   register int fromfd;
  24.   register int i;
  25.   register struct FileLock *destlock;
  26.   int curnum='0';
  27.  
  28.   static char bakname[256];
  29.  
  30. /* declare us some AmigaDOS functions: */
  31.   extern long DeleteFile();
  32.   extern struct FileLock *Lock();
  33.   extern void UnLock();
  34.   extern long Rename();
  35.  
  36.  
  37.     if (strEQ(to, "-")) {   /* cat it to stdout. */
  38. #ifdef DEBUGGING
  39.         if (debug & 4)
  40.             say2("Moving %s to stdout.\n", from);
  41. #endif
  42.         fromfd = open(from, 0);
  43.         if (fromfd < 0)
  44.             fatal2("patch: internal error, can't reopen %s\n", from);
  45.         while ((i=read(fromfd, buf, sizeof buf)) > 0)
  46.             if (write(1, buf, i) != 1)
  47.                 fatal1("patch: write failed\n");
  48.         Close(fromfd);
  49.         return 0;
  50.     }
  51.  
  52. /* add the extension to the name */
  53.     Strcpy(bakname, to);
  54. /* see if the "to" exists. If not, don't add the extension. */
  55.     if (destlock=Lock(bakname)) {
  56.         UnLock(destlock);
  57.         Strcat(bakname, ORIGEXT);
  58.  
  59.         i = strlen(bakname);   /* find the end of string */
  60.         bakname[i+1]=0;        /* so that the following will work: */
  61.  
  62. /* now to see if the destination exists: */
  63.         while (destlock=Lock(bakname)) {
  64.             UnLock(destlock);   /* clean up after ourselves. */
  65.             bakname[i]=curnum++;
  66.         }
  67. /* ok, now we can do the relinking! */
  68.         success = Rename(to,bakname);
  69.         if (success==0) {
  70.             say3("patch: can't backup %s, output is in %s\n",
  71.                 to, from);
  72.             return -1;
  73.         }
  74.     }
  75. /* ok, now copy the from to the to file. */
  76. /* try renaming it first, & if that don't work, then copy it. */
  77.     success = Rename(from,to);
  78.     if (success==0) {                  /* if don't work, then copy! */
  79.        copy_file(from,to);
  80.        success=DeleteFile(from);
  81.     }
  82.     return 0;
  83. }
  84. #endif
  85.  
  86. #ifndef AMIGA
  87. int
  88. move_file(from,to)
  89. char *from, *to;
  90. {
  91.     char bakname[512];
  92.     Reg1 char *s;
  93.     Reg2 int i;
  94.     Reg3 int fromfd;
  95.  
  96.     /* to stdout? */
  97.  
  98.     if (strEQ(to, "-")) {
  99. #ifdef DEBUGGING
  100.         if (debug & 4)
  101.             say2("Moving %s to stdout.\n", from);
  102. #endif
  103.         fromfd = open(from, 0);
  104.         if (fromfd < 0)
  105.             fatal2("patch: internal error, can't reopen %s\n", from);
  106.         while ((i=read(fromfd, buf, sizeof buf)) > 0)
  107.             if (write(1, buf, i) != 1)
  108.                 fatal1("patch: write failed\n");
  109.         Close(fromfd);
  110.         return 0;
  111.     }
  112.  
  113.         if (origprae) {
  114.                 Strcpy (bakname, origprae);
  115.         Strcat(bakname, to);
  116.         } else {
  117.                 Strcpy(bakname, to);
  118.         Strcat(bakname, origext?origext:ORIGEXT);
  119.         }
  120.     if (stat(to, &filestat) >= 0) {     /* output file exists */
  121.         dev_t to_device = filestat.st_dev;
  122.         ino_t to_inode  = filestat.st_ino;
  123.         char *simplename = bakname;
  124.  
  125.         for (s=bakname; *s; s++) {
  126.             if (*s == '/')
  127.                 simplename = s+1;
  128.         }
  129.         /* find a backup name that is not the same file */
  130.         while (stat(bakname, &filestat) >= 0 &&
  131.                 to_device == filestat.st_dev && to_inode == filestat.st_ino) {
  132.             for (s=simplename; *s && !islower(*s); s++) ;
  133.             if (*s)
  134.                 *s = toupper(*s);
  135.             else
  136.                 Strcpy(simplename, simplename+1);
  137.         }
  138.         while (unlink(bakname) >= 0) ;  /* while() is for benefit of Eunice */
  139. #ifdef DEBUGGING
  140.         if (debug & 4)
  141.             say3("Moving %s to %s.\n", to, bakname);
  142. #endif
  143.         if (link(to, bakname) < 0) {
  144.             say3("patch: can't backup %s, output is in %s\n",
  145.                 to, from);
  146.             return -1;
  147.         }
  148.         while (unlink(to) >= 0) ;
  149.     }
  150. #ifdef DEBUGGING
  151.     if (debug & 4)
  152.         say3("Moving %s to %s.\n", from, to);
  153. #endif
  154.     if (link(from, to) < 0) {           /* different file system? */
  155.         Reg4 int tofd;
  156.  
  157.         tofd = creat(to, 0666);
  158.         if (tofd < 0) {
  159.             say3("patch: can't create %s, output is in %s.\n",
  160.               to, from);
  161.             return -1;
  162.         }
  163.         fromfd = open(from, 0);
  164.         if (fromfd < 0)
  165.             fatal2("patch: internal error, can't reopen %s\n", from);
  166.         while ((i=read(fromfd, buf, sizeof buf)) > 0)
  167.             if (write(tofd, buf, i) != i)
  168.                 fatal1("patch: write failed\n");
  169.         Close(fromfd);
  170.         Close(tofd);
  171.     }
  172.     Unlink(from);
  173.     return 0;
  174. }
  175. #endif
  176.  
  177. /* Copy a file. */
  178.  
  179. void
  180. copy_file(from,to)
  181. char *from, *to;
  182. {
  183.     Reg3 int tofd;
  184.     Reg2 int fromfd;
  185.     Reg1 int i;
  186.  
  187.     tofd = creat(to, 0666);
  188.  
  189.     if (tofd < 0)
  190.         fatal2("patch: can't create %s.\n", to);
  191.     fromfd = open(from, 0);
  192.     if (fromfd < 0)
  193.         fatal2("patch: internal error, can't reopen %s\n", from);
  194.     while ((i=read(fromfd, buf, sizeof buf)) > 0)
  195.         if (write(tofd, buf, i) != i)
  196.             fatal2("patch: write (%s) failed\n", to);
  197.     Close(fromfd);
  198.     Close(tofd);
  199. }
  200.  
  201. /* Allocate a unique area for a string. */
  202.  
  203. char *
  204. savestr(s)
  205. Reg1 char *s;
  206. {
  207.     Reg3 char *rv;
  208.     Reg2 char *t;
  209.  
  210.     if (!s)
  211.         s = "Oops";
  212.     t = s;
  213.     while (*t++);
  214.     rv = malloc((MEM) (t - s));
  215.     if (rv == Nullch) {
  216.         if (using_plan_a)
  217.             out_of_mem = TRUE;
  218.         else
  219.             fatal1("patch: out of memory (savestr)\n");
  220.     }
  221.     else {
  222.         t = rv;
  223.         while (*t++ = *s++);
  224.     }
  225.     return rv;
  226. }
  227.  
  228. #ifdef lint
  229.  
  230. #ifdef CANVARARG
  231.  
  232. /*VARARGS ARGSUSED*/
  233. say(pat) char *pat; { ; }
  234. /*VARARGS ARGSUSED*/
  235. fatal(pat) char *pat; { ; }
  236. /*VARARGS ARGSUSED*/
  237. ask(pat) char *pat; { ; }
  238. #endif
  239.  
  240. #else
  241.  
  242. /* Vanilla terminal output (buffered). */
  243.  
  244. void
  245. say(pat,arg1,arg2,arg3)
  246. char *pat;
  247. long arg1,arg2,arg3;
  248. {
  249.     fprintf(stderr, pat, arg1, arg2, arg3);
  250.     Fflush(stderr);
  251. }
  252.  
  253. /* Terminal output, pun intended. */
  254.  
  255. void                            /* very void */
  256. fatal(pat,arg1,arg2,arg3)
  257. char *pat;
  258. long arg1,arg2,arg3;
  259. {
  260.     void my_exit();
  261.  
  262.     say(pat, arg1, arg2, arg3);
  263.     my_exit(1);
  264. }
  265.  
  266.  
  267. #ifndef AMIGA
  268.  
  269. /* Get a response from the user, somehow or other. */
  270.  
  271. void
  272. ask(pat,arg1,arg2,arg3)
  273. char *pat;
  274. long arg1,arg2,arg3;
  275. {
  276.     int ttyfd;
  277.     int r;
  278.     bool tty2 = isatty(2);
  279.  
  280.     Sprintf(buf, pat, arg1, arg2, arg3);
  281.     Fflush(stderr);
  282.     write(2, buf, strlen(buf));
  283.     if (tty2) {                         /* might be redirected to a file */
  284.         r = read(2, buf, sizeof buf);
  285.     }
  286.     else if (isatty(1)) {               /* this may be new file output */
  287.         Fflush(stdout);
  288.         write(1, buf, strlen(buf));
  289.         r = read(1, buf, sizeof buf);
  290.     }
  291.     else if ((ttyfd = open("/dev/tty", 2)) >= 0 && isatty(ttyfd)) {
  292.                                         /* might be deleted or unwriteable */
  293.         write(ttyfd, buf, strlen(buf));
  294.         r = read(ttyfd, buf, sizeof buf);
  295.         Close(ttyfd);
  296.     }
  297.     else if (isatty(0)) {               /* this is probably patch input */
  298.         Fflush(stdin);
  299.         write(0, buf, strlen(buf));
  300.         r = read(0, buf, sizeof buf);
  301.     }
  302.     else {                              /* no terminal at all--default it */
  303.         buf[0] = '\n';
  304.         r = 1;
  305.     }
  306.     if (r <= 0)
  307.         buf[0] = 0;
  308.     else
  309.         buf[r] = '\0';
  310.     if (!tty2)
  311.         say1(buf);
  312. }
  313. #else  /* Amiga */
  314.  
  315. /* for the Amiga we're going to have to do some heavy-duty magic.
  316.    We can't open /dev/tty! So open a whole new window!
  317. */
  318.  
  319. void
  320. ask(pat,arg1,arg2,arg3)
  321. char *pat;
  322. long arg1,arg2,arg3;
  323. {
  324.     int rwin;
  325.     long actual_read;
  326.  
  327.  
  328.     Sprintf(buf, pat, arg1, arg2, arg3);
  329.     rwin=open("CON:0/10/400/100/Patch Response Window",O_RDWR+O_CREAT);
  330.     if (rwin==0) {
  331.         printf("Error:No window dressing.");
  332.     }
  333.     write(rwin,buf,strlen(buf));
  334.     actual_read=read(rwin,buf,sizeof buf);
  335.     if (actual_read==0)
  336.        buf[0]=0;
  337.     buf[actual_read]=0;
  338. /*    printf("actual_read=%d buf=%s\n",actual_read,buf); */
  339.     Close(rwin);
  340. }
  341. #endif  /* amiga */
  342. #endif  /* lint */
  343.  
  344.  
  345. /* How to handle certain events when not in a critical region. */
  346.  
  347. void
  348. set_signals(reset)
  349.  int reset;
  350. {
  351.     void my_exit();
  352.  
  353. #ifdef AMIGA
  354.     extern short Enable_Abort;
  355.  
  356.     Enable_Abort=1;
  357.  
  358. #else
  359.  
  360. #ifndef lint
  361. #ifdef VOIDSIG
  362.     static void (*hupval)(),(*intval)();
  363. #else
  364.     static int (*hupval)(),(*intval)();
  365. #endif
  366.     if (!reset) {
  367.       hupval = signal(SIGHUP, SIG_IGN);
  368.       if (hupval != SIG_IGN)
  369. #ifdef VOIDSIG
  370.           hupval = my_exit;
  371. #else
  372.           hupval = (int(*)())my_exit;
  373. #endif
  374.       intval = signal(SIGINT, SIG_IGN);
  375.       if (intval != SIG_IGN)
  376. #ifdef VOIDSIG
  377.           intval = my_exit;
  378. #else
  379.           intval = (int(*)())my_exit;
  380. #endif
  381.     }
  382.     Signal(SIGHUP, hupval);
  383.     Signal(SIGINT, intval);
  384. #endif
  385.  
  386. #endif
  387. }
  388.  
  389. /* How to handle certain events when in a critical region. */
  390.  
  391. void
  392. ignore_signals()
  393. {
  394. #ifdef AMIGA
  395.   extern short Enable_Abort;
  396.  
  397.   Enable_Abort=0;
  398. #else
  399.  
  400. #ifndef lint
  401.     Signal(SIGHUP, SIG_IGN);
  402.     Signal(SIGINT, SIG_IGN);
  403. #endif
  404. #endif
  405.  
  406. }
  407.  
  408. #ifdef AMIGA
  409.  
  410. extern int stat();
  411.  
  412. /*
  413.   This is more space-efficient than Larry's, but has the
  414.   disadvantage of groking with the other person's copy of the
  415.   string. Restores it before the end, but that's still nasty.
  416. */
  417.  
  418. void
  419. makedirs(filename,striplast)
  420.   char *filename;
  421.   bool striplast;
  422. {
  423.     register char *walkptr=filename;
  424.     register char temp;
  425.     extern char *index();
  426.     register struct FileLock *tmplock;
  427.     register int result;
  428.  
  429.     extern struct FileLock *CreateDir();
  430.  
  431.     struct stat *buf;  /* for the stat() command. */
  432.  
  433. /* first the easy part: */
  434.     buf = (struct stat *) malloc(sizeof(struct stat));
  435.     if (walkptr[0]=='.' && walkptr[1]=='/')
  436.         walkptr+=2;
  437.     if (walkptr[0]=='/')  /* starting at root: */
  438.        walkptr[0]=':';    /* AmigaDOS root. */
  439.  
  440. /* loop: */
  441.  
  442.     for(;;) {
  443.         walkptr=index(walkptr,'/'); /* see if there's subdirectories. */
  444.         if (walkptr) {
  445.             temp=*walkptr;
  446.             *walkptr++=0;               /* filename now points to dirname. */
  447.         } else if (striplast)  /* top-of-loop exit, and... */
  448.             break;
  449.         result = stat(filename,buf);
  450.  
  451. /* If we can't create the directory, we'll sit here spinning till
  452.   the end of the filename. On the other hand, it don't really matter
  453.   what we do here. They won't be able to open the final file name upstairs,
  454.   so they'll say "can't create file" up there. Phew.
  455. */
  456.         if (result==-1) {   /* make a directory... */
  457.             tmplock=CreateDir(filename);
  458.             UnLock(tmplock);
  459.         }
  460.         if (walkptr)
  461.            *(walkptr-1)=temp; /* restore what we did to his filename. */
  462.         else
  463.             break;   /* bottom of loop exit. */
  464.     }
  465.     free(buf);
  466.     return;
  467. }
  468.  
  469. #else
  470.  
  471. /* Make sure we'll have the directories to create a file. */
  472.  
  473. void
  474. makedirs(filename,striplast)
  475. Reg1 char *filename;
  476. bool striplast;
  477. {
  478.     char tmpbuf[256];
  479.     Reg2 char *s = tmpbuf;
  480.     char *dirv[20];
  481.     Reg3 int i;
  482.     Reg4 int dirvp = 0;
  483.  
  484.     while (*filename) {
  485.         if (*filename == '/') {
  486.             filename++;
  487.             dirv[dirvp++] = s;
  488.             *s++ = '\0';
  489.         }
  490.         else {
  491.             *s++ = *filename++;
  492.         }
  493.     }
  494.     *s = '\0';
  495.     dirv[dirvp] = s;
  496.     if (striplast)
  497.         dirvp--;
  498.     if (dirvp < 0)
  499.         return;
  500.     strcpy(buf, "mkdir");
  501.     s = buf;
  502.     for (i=0; i<=dirvp; i++) {
  503.         while (*s) s++;
  504.         *s++ = ' ';
  505.         strcpy(s, tmpbuf);
  506.         *dirv[i] = '/';
  507.     }
  508.     system(buf);
  509.  
  510. }
  511.  
  512. #endif
  513.  
  514.  
  515. #ifdef AMIGA
  516.  
  517. /* chmod to satisfy us: */
  518.  
  519. void chmod() {}
  520.  
  521. /* abort to satisfy us: */
  522.  
  523. void abort() { exit(1); }
  524.  
  525. #endif
  526.  
  527. /* Make filenames more reasonable. */
  528.  
  529. char *
  530. fetchname(at,strip_leading,assume_exists)
  531. char *at;
  532. int strip_leading;
  533. int assume_exists;
  534. {
  535.     char *s;
  536.     char *name;
  537.     Reg1 char *t;
  538.     char tmpbuf[200];
  539.  
  540.     if (!at)
  541.         return Nullch;
  542.     s = savestr(at);
  543.     for (t=s; isspace(*t); t++) ;
  544.     name = t;
  545. #ifdef DEBUGGING
  546.     if (debug & 128)
  547.         say4("fetchname %s %d %d\n",name,strip_leading,assume_exists);
  548. #endif
  549.     if (strnEQ(name, "/dev/null", 9))   /* so files can be created by diffing */
  550.         return Nullch;                  /*   against /dev/null. */
  551.     for (; *t && !isspace(*t); t++)
  552.         if (*t == '/')
  553.             if (--strip_leading >= 0)
  554.                 name = t+1;
  555.     *t = '\0';
  556.     if (name != s && *s != '/') {
  557.         name[-1] = '\0';
  558.         if (stat(s, &filestat) && filestat.st_mode & S_IFDIR) {
  559.             name[-1] = '/';
  560.             name=s;
  561.         }
  562.     }
  563.     name = savestr(name);
  564.     Sprintf(tmpbuf, "RCS/%s", name);
  565.     free(s);
  566.     if (stat(name, &filestat) < 0 && !assume_exists) {
  567. #ifdef AMIGA
  568.         name = Nullch;   /* Amiga doesn't have RCS. */
  569. #else
  570.         Strcat(tmpbuf, RCSSUFFIX);
  571.         if (stat(tmpbuf, &filestat) < 0 && stat(tmpbuf+4, &filestat) < 0) {
  572.             Sprintf(tmpbuf, "SCCS/%s%s", SCCSPREFIX, name);
  573.             if (stat(tmpbuf, &filestat) < 0 && stat(tmpbuf+5, &filestat) < 0) {
  574.                 free(name);
  575.                 name = Nullch;
  576.             }
  577.         }
  578. #endif
  579.     }
  580.     return name;
  581. }
  582.